<?php
/**
 * Plugin is used to authenticate and authorize when a user logs in to Admin panel
 *
 * @package Admin
 * @subpackage Admin_Library
 * @category Controller_Plugin
 * @author 
 * @since $Id:$
 */
final class Admin_Library_Controller_Plugin_Auth extends Zend_Controller_Plugin_Abstract
{
    /** @var Zend_Acl $_acl */
    protected $_acl;

    /** @var string $_roleName */
    protected $_roleName;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->_roleName = Admin_Library_Constant::USR_ROLE_VISITOR;
        $this->_initAcl();
    }

    /**
     * initialize the acl object and resources
     * for the roles used in the application
     *
     */
    private function _initAcl()
    {
        // define access control list
        $this->_acl = new Zend_Acl();
        $this->_acl->addRole(new Zend_Acl_Role(Admin_Library_Constant::USR_ROLE_VISITOR));
        $this->_acl->addRole(new Zend_Acl_Role(Admin_Library_Constant::USR_ROLE_ADMIN),
                                Admin_Library_Constant::USR_ROLE_VISITOR);
        
        $this->_acl->addResource(new Zend_Acl_Resource('admin:ad'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:admin'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:category'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:config'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:customize'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:error'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:index'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:user'));
        $this->_acl->addResource(new Zend_Acl_Resource('admin:word'));
        
        $this->_acl->deny();
//        $this->_acl->allow(Admin_Library_Constant::USR_ROLE_VISITOR, 'admin:index', 'index');
        $this->_acl->allow(Admin_Library_Constant::USR_ROLE_VISITOR, 'admin:index', 'login');
        $this->_acl->allow(Admin_Library_Constant::USR_ROLE_VISITOR, 'admin:error', 'error');
        
        $this->_acl->allow(Admin_Library_Constant::USR_ROLE_ADMIN);
    }

    /**
     * Deny Access Function
     * Redirects to errorPage, this can be called from an action using the action helper
     *
     * @return void
     */
    public function denyAccess()
    {
        $this->_request->setModuleName("admin");
        $this->_request->setControllerName("index");
        $this->_request->setActionName("login");
    }

    /**
     * Predispatch
     * Checks if the current user identified by roleName has rights to the requested url (module/controller/action)
     * If not, it will call denyAccess to be redirected to errorPage
     *
     * @param Zend_Controller_Request_Abstract $request
     * @return void
     */
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $resourceName  = $request->getModuleName() . ':';
        $resourceName .= $request->getControllerName();
        
        /** Check if the controller/action can be accessed by the current user */
        if (!$this->_acl->isAllowed($this->_getRoleName(), $resourceName, $request->getActionName())) {
            /** Redirect to access denied page */
            $this->denyAccess();
        }
    }
    
    /**
     * Get the role name of logged-in user
     * 
     * @return string Role name
     */
    protected function _getRoleName()
    {
        $identity = Zend_Auth::getInstance()->getIdentity();
        if (!is_array($identity) || !isset($identity['role'])) {
            return $this->_roleName;
        }
        return $identity['role'];
    }
}